
import { Inject, Injectable } from '@angular/core';

import { RSocketClient, JsonSerializer, IdentitySerializer } from 'rsocket-core';
import RSocketWebSocketClient from 'rsocket-websocket-client';
import { Responder, Payload } from 'rsocket-types';
import { Single } from 'rsocket-flowable';

import { environment } from '@env/environment';
import { Subject } from 'rxjs';
import { SettingsService } from '@delon/theme';
import { StorageService } from '@core/storage/storage.sercvice';

@Injectable()
export class RsocketService {
  constructor(
    private settingService: SettingsService,
    private storageService: StorageService
  ) { }

  private responderSubject = new Subject<Payload<string, any>>();
  responder$ = this.responderSubject.asObservable();

  activeUserId = Number(this.settingService.user.id);
  

  client: RSocketClient;

  socket: any;

  async connect() {
    if(!this.client){
      const platform = await this.storageService.get('platform');
      const clientInfo: any = {
        userId: this.activeUserId,
        device: platform.device,
        deviceModel: platform.deviceModel,
        clientVersion: platform.clientVersion,
        tenantId: this.settingService.user.tenantId,
        status: '01'
      };

      this.client = new RSocketClient({
        serializers: {
          data: JsonSerializer,
          metadata: IdentitySerializer
        },
        setup: {
          payload: { data: clientInfo, metadata: String.fromCharCode('/chat'.length) + '/chat' },
          keepAlive: 60000,
          lifetime: 180000,
          dataMimeType: 'application/json',
          metadataMimeType: 'message/x.rsocket.routing.v0',
        },
        transport: new RSocketWebSocketClient({
          url: environment.rsocket.address
        }),
        responder: new MessageResponder(this),
      });
    }
    
    this.client.connect().then(socket => {
      this.socket = socket;
    }, (e) => console.log(e));

  }

  disconnect() {
    this.client.close();
  }


  responder(payload: Payload<string, any>){
    this.responderSubject.next(payload);
  }

}


class MessageResponder implements Responder<string, string> {

  constructor(private rsocketService: RsocketService) { }

  requestResponse(payload: Payload<string, any>): void {
    this.rsocketService.responder(payload.data);
    return Single.of('client response');
  }
}